% Author: Timothy Riley
% Class: CS3022 Programming Paradigms
% Professor: CDR Shaffer
% Reference: http://www.swi-prolog.org/pldoc/doc_for?object=section(2,'A.12',swi('/doc/Manual/lists.html'))
% Reference: http://cs.union.edu/~striegnk/learn-prolog-now/html/node96.html
% Description: Prolog implementation of prime diff which is satisfied iff List is a
%              list containing all the integers between 1 and Upper (inclusive) exactly
%              once, and the difference between any two consecutive numbers in List is
%              a prime number.


% Step 1: Verify the upper between 2 and 10
% Step 2: Generate a list of numbers from 1 to upper using numlist
% Step 3: Generate a list of all permutations of the list generated in step 2
% Step 4: Apply the permutation against the valid method
% Step 4a: If valid include in the resulting list
% Step 5: Return the list of permutations that hold prime_diff true
prime_diff(U,L) :- U >= 2, U =< 10, numlist(1,U,T), findall(X,(permutation(T,X), valid(X)),L).

% Method to obtain the length of a list
% Reference: CDR Shaffer Notes
% Param 1: List of elements
% Param 2: Result holding the length of the list
list_length([],0).
list_length([H|T],X) :- list_length(T,Y), X is Y + 1.

% Method to determine if difference between list elements are all prime
% Step 1: Get the length of the tail
% Step 2: If tail length >= 2 then
% Step 2a: Get the first element of the tail
% Step 2b: Subtract first element from the head
% Step 2c: Check if the difference is a prime
% Step 2d: Repeat
% Step 3: else
% Step 3a: Get the first element of the tail
% Step 3b: Subtract first element from the head
% Step 3c: Check if the difference is a prime
valid([]).
valid([H|T]) :- list_length(T,L), (L >= 2 -> nth0(0,T,H1), X is abs(H - H1), prime(X), valid(T) ; L == 1, nth0(0,T,H1), X is abs(H - H1), prime(X)).

% The prime numbers between 1 and 20 represented as facts
prime(2).
prime(3).
prime(5).
prime(7).
prime(11).
prime(13).
prime(17).
prime(19).